home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 2 / Apprentice-Release2.iso / Source Code / Pascal / Applications / ircle 1.5.1 / source / ircle sources / IRCCommands.p < prev    next >
Encoding:
Text File  |  1993-11-15  |  12.3 KB  |  540 lines  |  [TEXT/PJMM]

  1. {    ircle - Internet Relay Chat client    }
  2. {    File: IRCCommands    }
  3. {    Copyright © 1992 Olaf Titz (s_titz@ira.uka.de)    }
  4.  
  5. {    This program is free software; you can redistribute it and/or modify    }
  6. {    it under the terms of the GNU General Public License as published by    }
  7. {    the Free Software Foundation; either version 2 of the License, or    }
  8. {    (at your option) any later version.    }
  9.  
  10. {    This program is distributed in the hope that it will be useful,    }
  11. {    but WITHOUT ANY WARRANTY; without even the implied warranty of    }
  12. {    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    }
  13. {    GNU General Public License for more details.    }
  14.  
  15. {    You should have received a copy of the GNU General Public License    }
  16. {    along with this program; if not, write to the Free Software    }
  17. {    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.    }
  18.  
  19. unit IRCCommands;
  20. { Handles commands typed in by the user }
  21.  
  22. interface
  23. uses
  24.     TCPTypes, TCPStuff, TCPConnections, ApplBase, MiscGlue, MsgWindows, {}
  25.     IRCGlobals, IRCaux, IRCPreferences, IRCChannels, IRCHelp, {}
  26.     IRCNotify, IRCIgnore, DCC;
  27.  
  28. var
  29.     listmin, listmax: integer;
  30.     listpub, listpriv, listloc, listglob, listtop: boolean;     { Flags for /list display }
  31.  
  32. procedure HandleCommand (var s: string);
  33. { Process s as command line }
  34.  
  35. procedure sendCTCP (var t, s: string);
  36. { send CTCP message }
  37.  
  38. procedure RegUser;
  39. { Send the server the first commands to register the user }
  40.  
  41. implementation
  42.  
  43. { This procedure is to be run in the background, to type }
  44. { a file to the current channel. }
  45. procedure TypeCmd;
  46.     var
  47.         s, t: Str255;
  48.         f: text;
  49.     begin
  50.         t := CurrentTarget;
  51.         if t <> '' then begin
  52.             s := OldFileName(concat('Type to ', t, ':'));
  53.             if s <> '' then begin
  54.                 reset(f, s);
  55.                 s := concat('*** Typing ', s, '...');
  56.                 ChannelMsg(t, s);
  57.                 while not eof(f) do begin
  58.                     if flushing then begin
  59.                         flushing := false;
  60.                         leave;
  61.                     end;
  62.                     readln(f, s);
  63.                     if s <> '' then begin
  64.                         s := concat('PRIVMSG ', t, ' :', s);
  65.                         PutLine(s);
  66.                     end
  67.                 end;
  68.                 close(f);
  69.                 s := '*** Finished  TYPE';
  70.                 ChannelMsg(t, s);
  71.             end;
  72.         end
  73.     end;
  74.  
  75. procedure ParseComLine (var l: string; var com: str255; var rest: string);
  76.     var
  77.         i: integer;
  78.         c: char;
  79.     begin
  80.         if l[1] = cmdChar then
  81.             delete(l, 1, 1);
  82.         i := pos(' ', l);
  83.         if i = 0 then begin
  84.             com := copy(l, 1, 255);
  85.             rest := ''
  86.         end
  87.         else begin
  88.             com := copy(l, 1, i - 1);
  89.             while (i <= length(l)) and (l[i] = ' ') do
  90.                 i := succ(i);
  91.             rest := copy(l, i, 255)
  92.         end;
  93.         UprString(com, false);
  94.     end;
  95.  
  96. procedure DoServer (var rest: string);
  97.     var
  98.         i: longint;
  99.         s1, s2: string;
  100.     begin
  101.         NextArg(rest, s1);
  102.         NextArg(rest, s2);
  103.         if s1 <> '' then begin
  104.             case serverStatus of
  105.                 S_LOOKUP, S_OPENING, S_CLOSING: 
  106.                     begin
  107.                     StatusMsg(E_OPEN);
  108.                     exit(DoServer)
  109.                 end;
  110.                 S_CONN: 
  111.                     begin
  112.                     dirtyPrefs := true; { assuming change of servers }
  113.                     CloseConnection(sSocket);
  114.                     serverStatus := S_CLOSING;
  115.                     UpdateStatusLine;
  116.                     repeat
  117.                         ApplRun
  118.                     until serverStatus = S_OFFLINE;
  119.                     UpdateStatusLine;
  120.                 end;
  121.                 otherwise
  122.                     serverStatus := S_OFFLINE;
  123.             end;
  124.             default^^.server := s1;
  125.             if s2 <> '' then begin
  126.                 StringToNum(s2, i);
  127.                 default^^.port := integer(i);
  128.             end
  129.             else
  130.                 default^^.port := 6667;
  131.             OpenConnection;
  132.             if serverStatus = S_CONN then
  133.                 RegUser;
  134.         end;
  135.     end;
  136.  
  137. function match (var s1: string; s2: str20): boolean;
  138.     var
  139.         i, n: integer;
  140.     begin
  141.         i := length(s1);
  142.         if i = 0 then begin
  143.             match := false;
  144.             exit(match)
  145.         end;
  146.         n := length(s2);
  147.         if n > i then
  148.             n := i;
  149.         i := 1;
  150.         while i <= n do begin
  151.             if s1[i] <> s2[i] then begin
  152.                 match := false;
  153.                 exit(match)
  154.             end;
  155.             i := i + 1;
  156.         end;
  157.         match := true;
  158.     end;
  159.  
  160. procedure TranslateCommand (var s: string);
  161. { Translates aliases & processes internal commands }
  162. { Will return an empty string if command already processed }
  163. { Note: valid commands not mentioned here get sent to the server unprocessed anyway. }
  164. { That means that an error message for wrong commands comes always from the server. }
  165.     type
  166.         str8 = string[8];
  167.     var
  168.         com, rest, s1: str255;
  169.         i: integer;
  170.         l: longint;
  171.         dd: MWHndl;
  172.         b: boolean;
  173.     procedure twoargs (com: str8);
  174.         begin
  175.             NextArg(rest, s1);
  176.             s := concat(com, ' ', s1, ' :', rest)
  177.         end;
  178.     function nextnum: integer;
  179.         var
  180.             l: longint;
  181.         begin
  182.             NextArg(rest, s1);
  183.             stringtonum(s1, l);
  184.             nextnum := l
  185.         end;
  186.     procedure join;
  187.         begin
  188.             if rest = '' then
  189.                 rest := lastInvite;
  190.             MakeChannel(rest);
  191.             s := concat('JOIN :', rest);
  192.         end;
  193.     procedure part;
  194.         begin
  195.             MakeChannel(rest);
  196.             s := concat('PART :', rest)
  197.         end;
  198.     procedure signoff;
  199.         begin
  200.             if rest = '' then
  201.                 rest := 'Leaving';
  202.             s := concat('QUIT :', rest);
  203.             QuitRequest := true
  204.         end;
  205.     begin
  206.         ParseComLine(s, com, rest);
  207.         if match(com, 'AWAY') then begin
  208.             IsAway := (rest <> '');
  209.             UpdateStatusLine;
  210.             s := concat('AWAY :', rest);
  211.         end
  212.         else if match(com, 'BROADCAST') then begin
  213.             GetAllWindows(true, true, false, ',', com);
  214.             if com = '' then
  215.                 StatusMsg(E_NOTARGET)
  216.             else begin
  217.                 s := concat('>* ', rest);
  218.                 Message(s);
  219.                 s := concat('PRIVMSG ', com, ' :', rest)
  220.             end
  221.         end
  222.         else if match(com, 'BYE') then
  223.             signoff
  224.         else if match(com, 'CHANNEL') then
  225.             join
  226.         else if match(com, 'CMDCHAR') then begin
  227.             if rest <> '' then
  228.                 cmdChar := rest[1];
  229.             s := ''
  230.         end
  231.         else if match(com, 'CPING') then begin
  232.             GetDateTime(l);
  233.             NumToString(l, s1);
  234.             s := concat('PING ', s1);
  235.             sendCTCP(rest, s);
  236.             s := ''
  237.         end
  238.         else if match(com, 'CTCP') then begin
  239.             i := pos(' ', rest);
  240.             if i = 0 then begin
  241.                 com := rest;
  242.                 rest := ''
  243.             end
  244.             else begin
  245.                 com := copy(rest, 1, i - 1);
  246.                 delete(rest, 1, i)
  247.             end;
  248.             sendCTCP(com, rest);
  249.             s := ''
  250.         end
  251.         else if match(com, 'DATE') then
  252.             s := concat('TIME ', rest)
  253.         else if match(com, 'DCC') then begin
  254.             DCCcommand(rest);
  255.             s := ''
  256.         end
  257.         else if match(com, 'EXIT') then
  258.             signoff
  259.         else if match(com, 'FONT') then begin
  260.             NextArg(rest, s1);
  261.             StringToNum(s1, l);
  262.             MWDefaultFont := l;
  263.             StringToNum(rest, l);
  264.             MWDefaultSize := l;
  265.             AdjustFontMenu;
  266.             s := '';
  267.         end
  268.         else if match(com, 'HELP') then begin
  269.             ShowHelp;
  270.             s := ''
  271.         end
  272.         else if match(com, 'IGNORE') then begin
  273.             DoIgnore(rest);
  274.             s := ''
  275.         end
  276.         else if match(com, 'KICK') then
  277.             twoargs('KICK')
  278.         else if match(com, 'KILL') then
  279.             twoargs('KILL')
  280.         else if match(com, 'JOIN') then
  281.             join
  282.         else if match(com, 'LIST') then begin
  283.             listpub := true;
  284.             listpriv := true;
  285.             listloc := true;
  286.             listglob := true;
  287.             listtop := true;
  288.             listmin := 0;
  289.             listmax := maxint;
  290.             repeat
  291.                 if rest = '' then
  292.                     leave;
  293.                 if rest[1] = '-' then begin
  294.                     NextArg(rest, s1);
  295.                     UprString(s1, false);
  296.                     if s1 = '-MIN' then
  297.                         listmin := nextnum
  298.                     else if s1 = '-MAX' then
  299.                         listmax := nextnum
  300.                     else if match(s1, '-PUBLIC') then
  301.                         listpriv := false
  302.                     else if match(s1, '-PRIVATE') then
  303.                         listpub := false
  304.                     else if match(s1, '-LOCAL') then
  305.                         listglob := false
  306.                     else if match(s1, '-GLOBAL') then
  307.                         listloc := false
  308.                     else if match(s1, '-TOPIC') then
  309.                         listtop := false
  310.                 end
  311.                 else
  312.                     leave;
  313.             until false;
  314.             s := concat('LIST ', rest);
  315.         end
  316.         else if match(com, 'LEAVE') then
  317.             part
  318.         else if com = 'ME' then begin
  319.             s := concat(CurrentNick, ' ', rest);
  320.             Message(s);
  321.             s := concat('ACTION ', rest);
  322.             sendCTCP(currentTarget, s);
  323.             s := ''
  324.         end
  325.         else if match(com, 'MSG') then begin
  326.             NextArg(rest, s1);
  327.             if IsChannel(s1) then
  328.                 s := concat('> ', s1, ' ', rest)
  329.             else
  330.                 s := concat('> *', s1, '* ', rest);
  331.             ChannelMsg(s1, s);
  332.             s := concat('PRIVMSG ', s1, ' :', rest);
  333.         end
  334.         else if com = 'NICK' then begin
  335.             if default^^.nick = '' then begin
  336.                 default^^.nick := rest; { register default from prefs file }
  337.                 s := ''
  338.             end
  339.             else if CurrentNick = '' then
  340.                 CurrentNick := rest { register user }
  341.         end
  342.         else if com = 'NOTICE' then begin
  343.             NextArg(rest, s1);
  344.             s := concat('> -', s1, '- ', rest);
  345.             ChannelMsg(s1, s);
  346.             s := concat('NOTICE ', s1, ' :', rest)
  347.         end
  348.         else if match(com, 'NOTIFY') then begin
  349.             DoNotify(rest);
  350.             s := ''
  351.         end
  352.         else if match(com, 'QUERY') then begin
  353.             if rest = '' then begin
  354.                 if lastMSG <> '' then
  355.                     dd := DoJoin(lastMSG)
  356.             end
  357.             else
  358.                 dd := DoJoin(rest);
  359.             s := ''
  360.         end
  361.         else if match(com, 'QUIT') then
  362.             signoff
  363.         else if com = 'QUOTE' then
  364.             s := rest
  365.         else if match(com, 'SERVER') then begin
  366.             s := '';
  367.             DoServer(rest);
  368.         end
  369.         else if com = 'SHORTCUT' then begin
  370.             NextArg(rest, s1);
  371.             i := ord(s1[1]) - 48;
  372.             if i = 0 then
  373.                 i := 10;
  374.             if (i >= 1) and (i <= 10) then
  375.                 shortcuts^^[i] := rest;
  376.             s := ''
  377.         end
  378.         else if match(com, 'SHOW') then begin
  379.             UprString(rest, false);
  380.             NextArg(rest, s1);
  381.             b := (rest = 'ON') or (rest = '1');
  382.             if s1 = 'ALL' then begin
  383.                 showJOIN := b;
  384.                 showPART := b;
  385.                 showQUIT := b;
  386.                 showWALLOPS := b;
  387.                 showTOPIC := b;
  388.                 showINVITE := b;
  389.                 showNICK := b;
  390.                 showMODE := b;
  391.                 showKICK := b;
  392.                 showNAMES := b;
  393.             end
  394.             else if match(s1, 'JOIN') then
  395.                 showJOIN := b
  396.             else if match(s1, 'PART') then
  397.                 showPART := b
  398.             else if match(s1, 'QUIT') then
  399.                 showQUIT := b
  400.             else if match(s1, 'WALLOPS') then
  401.                 showWALLOPS := b
  402.             else if match(s1, 'TOPIC') then
  403.                 showTOPIC := b
  404.             else if match(s1, 'INVITE') then
  405.                 showINVITE := b
  406.             else if match(s1, 'MODE') then
  407.                 showMODE := b
  408.             else if match(s1, 'KICK') then
  409.                 showKICK := b
  410.             else if match(s1, 'NAMES') then
  411.                 showNAMES := b
  412.             else begin
  413.                 s := stringof('*** Display of status messages: JOIN:', showJOIN, ' PART:', showPART, ' QUIT:', showQUIT, ' WALLOPS:', showWALLOPS, ' TOPIC:', showTOPIC, ' INVITE:', showINVITE, ' MODE:', showMODE, ' KICK:', showKICK, ' NAMES:', showNAMES);
  414.                 Message(s);
  415.             end;
  416.             s := ''
  417.         end
  418.         else if match(com, 'SIGNOFF') then
  419.             signoff
  420.         else if match(com, 'SQUIT') then
  421.             twoargs('SQUIT')
  422.         else if match(com, 'TOPIC') then
  423.             twoargs('TOPIC')
  424.         else if match(com, 'TYPE') then begin
  425.             i := ApplCoroutine(@TypeCmd, COSPACE);
  426.             s := ''
  427.         end
  428.         else if com = 'USERNAME' then begin
  429.             default^^.username := rest;
  430.             s := ''
  431.         end
  432.         else if com = 'USERINFO' then begin
  433.             default^^.userLoginname := rest;
  434.             s := ''
  435.         end
  436.         else if com = 'USERNOTIFY' then begin
  437.             for i := 1 to 4 do
  438.                 default^^.notify[i] := (rest[i] = '1');
  439.             s := '';
  440.         end
  441.         else if com = 'VERSION' then begin
  442.             if rest = '' then begin
  443.                 s := concat('Client is ircle ', CL_VERSION);
  444.                 Message(s);
  445.             end;
  446.             s := concat('VERSION ', rest);
  447.         end
  448.         else if com = 'WINDOW' then begin
  449.             SetRect(windowarg, nextnum, nextnum, nextnum, nextnum);
  450.             s := ''
  451.         end
  452.         else if (com = 'WHO') or (com = 'NAMES') then begin
  453.             if rest = '' then
  454.                 if CurrentTarget <> '' then
  455.                     s := concat(com, ' ', CurrentTarget);
  456.         end
  457.         else if match(com, 'WHOIS') then begin
  458.             if rest = '' then
  459.                 s := concat('WHOIS ', lastMSG)
  460.             else
  461.                 s := concat('WHOIS ', rest);
  462.         end
  463.     end;
  464.  
  465.  
  466. procedure sendCTCP (var t, s: string);
  467.     var
  468.         i: integer;
  469.         com: str255;
  470.     begin
  471.         if serverStatus = S_CONN then begin
  472.             i := pos(' ', s);
  473.             if i = 0 then begin
  474.                 com := s;
  475.                 s := ''
  476.             end
  477.             else begin
  478.                 com := copy(s, 1, i - 1);
  479.                 delete(s, 1, i);
  480.             end;
  481.             UprString(com, false);
  482.             s := concat('PRIVMSG ', t, ' :', chr(1), com, ' ', s, chr(1));
  483.             PutLine(s);
  484.         end
  485.         else
  486.             StatusMsg(E_NOSERVER);
  487.     end;
  488.  
  489. procedure HandleCommand (var s: string);
  490.     begin
  491.         flushing := false;
  492.         UpdateStatusLine;
  493.         TranslateCommand(s);
  494.         if s <> '' then begin
  495.             if serverStatus = S_CONN then begin
  496.                 PutLine(s);
  497.                 s := ''
  498.             end
  499.             else
  500.                 StatusMsg(E_NOSERVER);
  501.         end
  502.     end;
  503.  
  504. procedure RegUser;
  505.     var
  506.         s0, s: string;
  507.         i: integer;
  508.     begin
  509.         if not UserRegistered then begin
  510.             SetMainTitle(CurrentNick);
  511.             CurrentServer := ''; { server will respond with NOTICE }
  512.             serverVersion := SV_27; { others will generate specific responses }
  513.             s := concat('NICK ', currentNick);
  514.             HandleCommand(s);
  515.             s0 := default^^.userLoginName;
  516.             i := pos('@', s0);
  517.             if i > 0 then
  518.                 s := concat('USER ', copy(s0, 1, i - 1), ' ', copy(s0, i + 1, 255), ' . :', default^^.username)
  519.             else
  520.                 s := concat('USER ', s0, ' . . :', default^^.username);
  521.             HandleCommand(s);
  522.             s0 := default^^.autoExec;
  523.             while s0 <> '' do begin
  524.                 i := pos(';', s0);
  525.                 if i = 0 then
  526.                     i := 255;
  527.                 s := copy(s0, 1, i - 1);
  528.                 HandleCommand(s);
  529.                 delete(s0, 1, i)
  530.             end;
  531.             GetAllWindows(true, false, false, ',', s0);
  532.             if s0 <> '' then begin
  533.                 s := concat('JOIN :', s0);
  534.                 HandleCommand(s)
  535.             end;
  536.             UserRegistered := true
  537.         end
  538.     end;
  539.  
  540. end.